{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 推导式练习题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 用列表推导式生成[0, 3, 6, 9, 12, 15]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 过滤掉长度小于3的字符串列表，并将剩下的转换成大写字母 \n",
    "\n",
    "lst = [\"1\",\"2\",\"3\",\"4\",\"8\",\"weeff\",\"bdskjk\",\"nsdjj\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. 请根据所给x，用列表推导式生成[[1517991992.94, 100],\n",
    " [1517992000.94, 200],\n",
    " [1517992014.94, 300],\n",
    " [1517992744.94, 350],\n",
    " [1517992800.94, 280]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = {'name':'alex','Values':[{'timestamp':1517991992.94,'values':100,},{'timestamp': 1517992000.94,'values': 200,},\n",
    "{'timestamp': 1517992014.94,'values': 300,},{'timestamp': 1517992744.94,'values': 350},{'timestamp': 1517992800.94,'values': 280}],}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 函数复习"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 函数的参数\n",
    "\n",
    "函数在声明参数时大概有下面 4 种形式：\n",
    "\n",
    "1. 位置参数：`def func(a, b): pass`\n",
    "2. 关键字参数：`def func(a, b=1): pass`\n",
    "3. 任意位置参数：`def func(a, b=1, *c): pass`\n",
    "4. 任意关键字参数：`def func(a, b=1, *c, **d): pass`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "def power(x):\n",
    "    return x * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "power(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在，如果我们要计算x的3次方怎么办？可以再定义一个power3函数，但是如果要计算x的4次方、x的5次方……怎么办？我们不可能定义无限多个函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def power(x, n=2):\n",
    "    pass\n",
    "power(2, 2)\n",
    "power(3, 5)\n",
    "power(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用默认参数有什么好处？最大的好处是能降低调用函数的难度。\n",
    "\n",
    "举个例子，我们写个一年级小学生注册的函数，需要传入name和gender两个参数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Jane\n",
      "gender: F\n"
     ]
    }
   ],
   "source": [
    "def enroll(name, gender):\n",
    "    print('name:', name)\n",
    "    print('gender:', gender)\n",
    "enroll('Jane', 'F')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Jane\n",
      "gender: F\n",
      "age: 7\n",
      "city: shijiazhuang\n"
     ]
    }
   ],
   "source": [
    "def enroll(name, gender, age=7, city='shijiazhuang'):\n",
    "    print('name:', name)\n",
    "    print('gender:', gender)\n",
    "    print('age:', age)\n",
    "    print('city:', city)\n",
    "enroll('Jane', 'F')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Bill\n",
      "gender: M\n",
      "age: 8\n",
      "city: shijiazhuang\n"
     ]
    }
   ],
   "source": [
    "enroll('Bill', 'M', 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Billy\n",
      "gender: M\n",
      "age: 7\n",
      "city: baoding\n"
     ]
    }
   ],
   "source": [
    "enroll('Billy', 'M', city='baoding')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这样，大多数学生注册时不需要提供年龄和城市，只提供必须的两个参数\n",
    "\n",
    "只有与默认参数不符的学生才需要提供额外的信息："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任意位置参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Python函数中，还可以定义任意位置参数。顾名思义，可变参数就是传入的参数个数是可变的，可以是1个、2个到任意个，还可以是0个。\n",
    "\n",
    "我们以数学题为例子，给定一组数字a，b，c……，请计算a2 + b2 + c2 + ……。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [1, 2, 3]\n",
    "def calc(*numbers):\n",
    "    sum = 0\n",
    "    for n in numbers:\n",
    "        sum = sum + n * n\n",
    "    print(numbers)\n",
    "    return sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "55"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "calc(1, 2, 3, 4, 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 3)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "14"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "calc(*l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "91"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l2 = [1, 2, 3, 4, 5, 6]\n",
    "calc(*l2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任意位置参数允许你传入0个或任意个参数，这些可变参数在函数调用时自动组装为一个tuple。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假设就是有一个要处理的数是一个列表，有这样的一个可变位置参数的函数，是不是就不能用了？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*l表示把l这个list的所有元素作为可变参数传进去。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任意关键字参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任意关键字参数允许你传入0个或任意个含参数名的参数，这些关键字参数在函数内部自动组装为一个dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def person(name, age, **kw):\n",
    "    print('name:', name, 'age:', age, 'other:', kw)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Tracy age: 10 other: {'city': 'shijiazhuang', 'gender': 'F', 'weight': '30kg'}\n"
     ]
    }
   ],
   "source": [
    "person('Tracy', 10, city=\"shijiazhuang\", gender='F', weight='30kg')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这时候你可以传入任意个数的关键字参数："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者这种情况："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}\n"
     ]
    }
   ],
   "source": [
    "extra = {'city': 'Beijing', 'job': 'Engineer'}\n",
    "person('Jack', 24, city=extra['city'], job=extra['job'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}\n"
     ]
    }
   ],
   "source": [
    "person('Jack', 24, **extra)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这样更简单"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "autoscroll": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 'c')"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def foo(arg1='a', arg2='b'):\n",
    "    return arg1, arg2\n",
    "\n",
    "foo(arg2='c', arg1='d')\n",
    "foo(1, 2)\n",
    "foo(1, arg2='c')  # TypeError"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "autoscroll": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-34-00b2e28caf7f>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-34-00b2e28caf7f>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m    def foo(arg1='a', arg2):  # SyntaxError\u001b[0m\n\u001b[0m           ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "def foo(arg1='a', arg2):  # SyntaxError\n",
    "    return arg1, arg2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def concat(*lst,sep='|'):\n",
    "    return sep.join((str(i) for i in lst))\n",
    "print(concat('G', 30, '-'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "autoscroll": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a = 5 b = 2 c = 8\n"
     ]
    }
   ],
   "source": [
    "def f(a, b, c):\n",
    "    print(\"a =\", a, \"b =\", b, \"c =\", c)\n",
    "\n",
    "d = {\"a\":5, \"c\":8, \"b\":2}\n",
    "f(**d)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 匿名函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请用匿名函数改造下面的代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_odd(n):\n",
    "    return n % 2 == 1\n",
    "\n",
    "L = list(filter(lambda x: x*2, range(1, 20)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 装饰器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "def display_time(func):\n",
    "    def wrapper(*maxnum):\n",
    "        t1 = time.time()\n",
    "        result = func(*maxnum)\n",
    "        t2 = time.time()\n",
    "        print(t2 - t1)\n",
    "        return result\n",
    "    return wrapper"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "#这是一个判断一个数是否为质数的函数\n",
    "def is_prime(num):\n",
    "    if num < 2:\n",
    "        return False\n",
    "    elif num == 2:\n",
    "        return True\n",
    "    else:\n",
    "        for i in range(2, num):\n",
    "            if num % i == 0:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "display_time(prime_num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "@display_time\n",
    "def prime_num(maxnum):\n",
    "    count = 0\n",
    "    for i in range(2, maxnum):\n",
    "        if is_prime(i):\n",
    "            count += 1\n",
    "    return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.21317720413208008\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "669"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prime_num(5001)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
